
package com.jy.framework.sys.service.impl;


import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.jy.framework.exception.MyException;
import com.jy.framework.sys.service.*;
import com.jy.framework.sys.shiro.UsernamePasswordUserTypeToken;
import com.jy.framework.utils.Constant;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jy.framework.annotation.DataFilter;
import com.jy.framework.constant.UserStatusEnum;
import com.jy.framework.constant.UserTypeEnum;
import com.jy.framework.utils.PageUtils;
import com.jy.framework.utils.Query;
import com.jy.framework.sys.dao.SysUserDao;
import com.jy.framework.sys.entity.SysDeptEntity;
import com.jy.framework.sys.entity.SysRoleEntity;
import com.jy.framework.sys.entity.SysUserEntity;
import com.jy.framework.sys.shiro.ShiroUtils;

import javax.validation.constraints.NotNull;


/**
 * 系统用户
 *
 * @author chenshun
 * @email sunlightcs@gmail.com
 * @date 2016年9月18日 上午9:46:09
 */
@Service("sysUserService")
public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUserEntity> implements SysUserService {
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysDeptService sysDeptService;
    @Autowired
    private SysRoleService sysRoleService;
	@Autowired
	private SysRoleDeptService sysRoleDeptService;
    @Override
    public List<Long> queryAllMenuId(Long userId) {
        return baseMapper.queryAllMenuId(userId);
    }

    @Override
	public PageUtils queryPage(Map<String, Object> params) {
        String username = (String) params.get("username");
		IPage<SysUserEntity> page = this.page(
			new Query<SysUserEntity>(params).getPage(),
			new QueryWrapper<SysUserEntity>()
					.lambda()
					.and(StrUtil.isNotBlank(username),
							q->q.like(SysUserEntity::getUsername,username)
									.or()
									.like(SysUserEntity::getFullName,username)
									.or()
									.like(SysUserEntity::getMobile,username)
					)
				.inSql(params.get(Constant.SQL_FILTER) != null,SysUserEntity::getDeptId, (String)params.get(Constant.SQL_FILTER))
		);
        List<SysUserEntity> records = page.getRecords();
        List<Long> deptIds = records.stream().map(SysUserEntity::getDeptId).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(deptIds)){
            return new PageUtils(page);
        }
        Collection<SysDeptEntity> sysDeptEntities = sysDeptService.listByIds(deptIds);
        Map<Long, SysDeptEntity> deptEntityMap = sysDeptEntities.stream().collect(Collectors.toMap(k -> k.getId(), v -> v));

        for(SysUserEntity sysUserEntity : records){
			SysDeptEntity sysDeptEntity = deptEntityMap.get(sysUserEntity.getDeptId());
			if(sysDeptEntity!=null){
				sysUserEntity.setDeptName(sysDeptEntity.getName());
			}
		}

		return new PageUtils(page);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean saveOrRole(SysUserEntity user) {
		user.setCreateTime(new Date());
		//sha256加密
		String salt = RandomStringUtils.randomAlphanumeric(20);
		user.setSalt(salt);
		user.setPassword(ShiroUtils.sha256(user.getPassword(), user.getSalt()));
		if(user.getUserType() == null){
			user.setUserType(0);
		}
		this.save(user);
		
		//保存用户与角色关系
		sysUserRoleService.saveOrUpdate(user.getId(), user.getRoleIdList());
		
		return true;
	}

	public static void main(String[] args) {
		String salt = "bR2KP6ggHUV3YnTa07BY";
		System.out.println(ShiroUtils.sha256("admin", salt));
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void update(SysUserEntity user) {
		if(user.getUserType() == null){
			user.setUserType(0);
		}
		if (StringUtils.isBlank(user.getPassword())) {
			user.setPassword(null);
		}else{
			user.setPassword(ShiroUtils.sha256(user.getPassword(), user.getSalt()));
		}


		QueryWrapper<SysUserEntity> q=new QueryWrapper<>();
		q.lambda()
				.eq(SysUserEntity::getId,user.getId())
				;
//		update(user,q);

		this.updateById(user);
		
		//保存用户与角色关系
		sysUserRoleService.saveOrUpdate(user.getId(), user.getRoleIdList());
	}


	@Override
	public boolean updatePassword(Long userId, String password, String newPassword) {
        SysUserEntity userEntity = new SysUserEntity();
        userEntity.setPassword(newPassword);
        return this.update(userEntity,
                new QueryWrapper<SysUserEntity>().eq("id", userId).eq("password", password));
    }


	@Override
    public int allotBatch(Long[] userIds){
	    return baseMapper.allotBatch(userIds);
    }

    @Override
    public List<Map<String, Object>> getAllBy(Map<String, Object> params) {
        return baseMapper.getAllBy(params);
    }

	@Override
	public void doLogin(String username, String password, Integer userType) {
		try{
			Subject subject = ShiroUtils.getSubject();
			//UsernamePasswordToken token = new UsernamePasswordToken(username, password);
			UsernamePasswordUserTypeToken token=new UsernamePasswordUserTypeToken(username,password,userType);
			subject.login(token);
		}catch (UnknownAccountException e) {
			throw new MyException(e.getMessage());
		}catch (IncorrectCredentialsException e) {
			throw new MyException("账号或密码不正确");
		}catch (LockedAccountException e) {
			throw new MyException("账号已被锁定,请联系管理员");
		}catch (AuthenticationException e) {
			throw new MyException("账户验证失败");
		}
	}

	@Override
	public SysUserEntity selectByUsername(String username) {
        SysUserEntity  user = baseMapper.selectOne(new QueryWrapper<SysUserEntity>().lambda().eq(SysUserEntity::getUsername, username));
        if (null ==user){
        	return null;
		}
		//用户角色对应的部门ID列表
		List<Long> roleIdList = sysUserRoleService.queryRoleIdList(user.getId());
		if(roleIdList.size() > 0){
			List<Long> userDeptIdList = sysRoleDeptService.queryDeptIdList(roleIdList.toArray(new Long[roleIdList.size()]));
			user.setDataScopeDeptIds(userDeptIdList);
		}
		//用户子部门ID列表
		Long deptId = user.getDeptId();
		if (deptId !=null){
			List<Long> subDeptIdList = sysDeptService.getSubDeptIdList(deptId);
			user.setSubDeptIds(subDeptIdList);

		//		用户部门信息
			SysDeptEntity sysDeptEntity = sysDeptService.getById(deptId);
			user.setDeptName(sysDeptEntity.getName());
		}else {
			user.setSubDeptIds(new ArrayList<>());
		}

		return user;
	}


}
